#include "billboardvideoeffect.h"
#include "effectcontainermanager.h"
#include <osgViewer\View>
#include "datatypedefine.h"
#include "datamanager.h"
#include "utility.h"

namespace VrDataCore
{
	BillboardVideoEffectDrawable::BillboardVideoEffectDrawable(CoreBase::ActorBase* owneractor):Drawable(owneractor,"BillboardVideoEffectDrawable")
	{
		_drawable = new CoreBase::PlaneShape;
		_billboardNode = new osg::Billboard();
		_billboardNode->setMode(osg::Billboard::AXIAL_ROT);
		_billboardNode->setAxis(osg::Vec3(0.0f,0.0f,1.0f));
	}

	void BillboardVideoEffectDrawable::reset(const osg::Vec3& p1,const osg::Vec3& p2,const osg::Vec3& p3,const osg::Vec3& p4,
			const osg::Vec2& t1,const osg::Vec2& t2,const osg::Vec2& t3,const osg::Vec2& t4,osg::StateSet* ss)
	{
		_billboardNode->removeDrawables(0,_billboardNode->getNumDrawables());
		_drawable.get()->reset(p1,p2,p3,p4,t1,t2,t3,t4,ss);
		_billboardNode->addDrawable(_drawable.get()->getPlaneAsDrawable());
	}

	osg::Node* BillboardVideoEffectDrawable::getOSGNode()
	{
		return _billboardNode;
	}

	const osg::Node* BillboardVideoEffectDrawable::getOSGNode() const
	{
		return _billboardNode;
	}

	void BillboardVideoEffectDrawable::setPosition(const osg::Vec3& pos)
	{
		_billboardNode->setPosition(0,pos);
	}

	BillboardVideoEffect::BillboardVideoEffect():_ve(NULL),_loop(false)
		,_autounApply(false),_setupCallback(false)
	{}

	BillboardVideoEffect::~BillboardVideoEffect()
	{}

	void BillboardVideoEffect::buildPropertyMap()
	{}

	void BillboardVideoEffect::apply(CoreBase::ActorBase* actor)
	{
		if(!isIdle())
			return;
		//osgViewer::View* v = EffectContainerManager::GetInstance().getMainView();
		//int w = v->getCamera()->getViewport()->width();
		//int h = v->getCamera()->getViewport()->height();
		int w = 160;
		int h = 180;
		if(!_ve.valid())
		{
			_ve = new VideoEffect;
			_ve->init();
		}
		QString vf = DataManager::GetInstance().getApplicationDir() + CONTEXT_DIR + SCENE_VIDEO + "\\"+_videofile;
		_ve->loadVideo(ChineseTexttoStdstring(vf));
		bool flip = _ve->isFlip();
		dynamic_cast<BillboardVideoEffectDrawable*>(_drawable.get())->reset(
			osg::Vec3(-w,0,0),osg::Vec3(w,0,0),osg::Vec3(w,0,h),osg::Vec3(-w,0,h),
			flip?osg::Vec2(0,_ve->getVideoHeight()):osg::Vec2(0,0),
			flip?osg::Vec2(_ve->getVideoWidth(),_ve->getVideoHeight()):osg::Vec2(_ve->getVideoWidth(),0),
			flip?osg::Vec2(_ve->getVideoWidth(),0):osg::Vec2(_ve->getVideoWidth(),_ve->getVideoHeight()),
			flip?osg::Vec2(0,0):osg::Vec2(0,_ve->getVideoHeight()));
		_videoLength = _ve->getVideoLength()*1000;
		_startT = osg::Timer::instance()->tick();
		
		if(actor == NULL)
			EffectContainerManager::GetInstance().addEffectNode(_drawable->getOSGNode());
		else
			actor->getDrawable()->getOSGNode()->asGroup()->addChild(_drawable->getOSGNode());
		_ve->apply(this);
		EffectBase::apply(actor);
		setAutounApply(_autounApply);
		setLoop(_loop);
		setPosition(_position);
	}

	void BillboardVideoEffect::unApply(CoreBase::ActorBase* actor)
	{
		if(isIdle())
			return;
		if(_setupCallback)
		{
			EffectContainerManager::GetInstance().getRootDrawable()->getOSGNode()->removeUpdateCallback(_videoUpdateCallback);
			_setupCallback = false;
		}
		if(_bindingMeshDrawableActor==NULL)
			EffectContainerManager::GetInstance().removeEffectNode(_drawable->getOSGNode());
		else
			_bindingMeshDrawableActor->getDrawable()->getOSGNode()->asGroup()->removeChild(_drawable->getOSGNode());
		_ve->unApply(this);
		EffectBase::unApply(actor);
	}

	void BillboardVideoEffect::createDrawable()
	{
		_drawable = new BillboardVideoEffectDrawable(this);
	}

	void BillboardVideoEffect::setVideoFileName(QString f)
	{
		_videofile = f;
	}

	QString BillboardVideoEffect::getVideoFileName()
	{
		return _videofile;
	}

	void BillboardVideoEffect::callback()
	{
		if(isIdle())
			return;
		osg::Timer_t nowtime = osg::Timer::instance()->delta_m(_startT,osg::Timer::instance()->tick());
		if(nowtime>_videoLength)
		{
			unApply(this);
		}
	}

	void BillboardVideoEffect::setLoop(bool loop)
	{
		_loop = loop;
		if(isIdle())
			return;
		_ve->setLoop(_loop);
	}

	void BillboardVideoEffect::setAutounApply(bool autounapply)
	{
		_autounApply = autounapply;
		if(isIdle())
			return;
		if(_autounApply)
		{
			if(!_videoUpdateCallback.valid())
				_videoUpdateCallback = new BillboardVideoUpdateCallback(this);
			if(!_setupCallback)
				EffectContainerManager::GetInstance().getRootDrawable()->getOSGNode()->addUpdateCallback(_videoUpdateCallback);
			_setupCallback = true;
		}
		else
		{
			if(_videoUpdateCallback.valid() && _setupCallback)
				EffectContainerManager::GetInstance().getRootDrawable()->getOSGNode()->removeUpdateCallback(_videoUpdateCallback);
			_setupCallback = false;
		}
	}

	void BillboardVideoEffect::setPosition(const osg::Vec3& pos)
	{
		_position = pos;
		if(isIdle())
			return;
		dynamic_cast<BillboardVideoEffectDrawable*>(_drawable.get())->setPosition(_position);
	}
}